home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / jam / jamdisk1 / bio / source.run / Biorhythm.c next >
Encoding:
C/C++ Source or Header  |  1992-07-07  |  18.4 KB  |  687 lines

  1. /*  Biorhythm.c  */
  2.  
  3. /***************************************************************************
  4.  *                                       *
  5.  *  Program to calculate an individual's Biorhythms               *
  6.  *                                       *
  7.  *  written by:  Kevin Rahe, Reliable Software                   *
  8.  *                                       *
  9.  *  last updated:  1-25-87                           *
  10.  *                                       *
  11.  ***************************************************************************/
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <graphics/gfxbase.h>
  16. #include <graphics/gfxmacros.h>
  17. #include <graphics/text.h>
  18. #include <intuition/intuition.h>
  19. #include <ffp.h>
  20. #include <dates.h>
  21.  
  22. #define INTUITION_REV   33
  23. #define MAXPOINTS    20
  24. #define AREAX        40
  25. #define AREAY        40
  26. #define LPOSX        175
  27. #define LPOSY        20
  28. #define RPOSX        212
  29. #define RPOSY        20
  30. #define BPOSX        20
  31. #define BPOSY        23
  32. #define GRAPHX        30
  33. #define GRAPHY        54
  34.  
  35. #define REQWIDTH    306
  36. #define REQHEIGHT    106
  37. #define REQLINES    7
  38.  
  39.     /*******  graphing constants  *******/
  40. #define LEGY        46
  41. #define BKGD        1
  42. #define PHYSPEN        0
  43. #define EMOTPEN        2
  44. #define INTEPEN        3
  45. #define PHYSICAL    23
  46. #define EMOTIONAL    28
  47. #define INTELLECTUAL    33
  48. #define PMULT        3.660563691
  49. #define EMULT        4.456338407
  50. #define IMULT        5.252113122
  51.  
  52. SHORT Arrow1[8] = { 1,6, 21,1, 21,11, 1,6 };
  53. USHORT Arrow2[8] = { 1,1, 21,6, 1,11, 1,1 };
  54. USHORT ArrowBox[10] = { 0,0, 24,0, 24,14, 0,14, 0,0 };
  55. USHORT BDateBox[10] = { 0,0, 93,0, 93,13, 0,13, 0,0 };
  56. char *monthname[] = {"January", "February", "March", "April", "May", "June",
  57.     "July", "August", "September", "October", "November", "December" };
  58.  
  59. char *aboutdata[] = { "Biorhythm Calculator v1.1",
  60.               "by Kevin Rahe",
  61.               "",
  62.               "Provided as an example of using",
  63.               "the Motorola FFP math functions",
  64.               "with Lattice C.  Hope you like it!",
  65.               "MAY BE FREELY DISTRIBUTED"
  66.              };
  67.  
  68. /******  function declarations  ******/
  69. void drawtriangles();
  70. void dogadgets();
  71. void newgraphsize();
  72. void drawgraph();
  73. void displegend();
  74. void newmonth();
  75. void domenu();
  76.  
  77. struct IntuitionBase *IntuitionBase;
  78. struct GfxBase *GfxBase;
  79. struct Window *MyWindow, *OpenWindow();
  80. struct RastPort *rp;
  81. struct Remember *RememberKey;
  82. struct IntuiMessage *IMsg, *GetMsg();
  83. struct TmpRas MyTmpRas;
  84. PLANEPTR MyPlane;
  85. struct IntuiText aboutarray[REQLINES];
  86. struct TextFont *font, *OpenFont();
  87. char datebuffer[11];        /*  buffer area for Birthdate string gadget  */
  88. int dayspan = 0;        /*  # of days between birth & 1st of month  */
  89. int month;            /*  current month  */
  90. FFP numdays;            /*  number of days in current month  */
  91. FFP pmult, emult, imult;    /*  FFP equivalents of #defined multipliers  */
  92. struct JULDATE sysdate, birthdate;
  93.  
  94.  
  95. /****************  TextAttr structure  ****************/
  96. struct TextAttr eightyfont = {
  97.     "topaz.font",        /*  ta_Name  */
  98.     8,            /*  ta_YSize  */
  99.     NULL,            /*  ta_Style  */
  100.     NULL            /*  ta_Flags  */
  101.     };
  102.  
  103.  
  104. /******************************************************/
  105. /******************  About Requester  *****************/
  106. /******************************************************/
  107.  
  108. /**************  IntuiText for Requester  *************/
  109. struct IntuiText texttemplate = {
  110.     0, 1,        /*  FrontPen, BackPen  */
  111.     JAM2,        /*  DrawMode  */
  112.     NULL, NULL,    /*  LeftEdge, TopEdge    (set at runtime)  */
  113.     &eightyfont,    /*  Font  */
  114.     NULL,        /*  IText        (set at runtime)  */
  115.     NULL        /*  NextText        (set at runtime)  */
  116.     };
  117.  
  118. struct IntuiText OkText = {
  119.     0, 1,        /*  FrontPen, BackPen  */
  120.     JAM2,        /*  DrawMode  */
  121.     6, 3,        /*  LeftEdge, TopEdge  */
  122.     &eightyfont,    /*  Font  */
  123.     "Ok",        /*  IText  */
  124.     NULL        /*  NextText  */
  125.     };
  126.  
  127.  
  128. /******************************************************/
  129. /*****************  Birthdate Gadget  *****************/
  130. /******************************************************/
  131.  
  132. /***********  Border for BirthDate Gadget  ************/
  133. struct Border BDateBorder = {
  134.     -3, -3,        /*  LeftEdge, TopEdge  */
  135.     3, 0,        /*  FrontPen, BackPen  */
  136.     JAM1,        /*  drawing mode */
  137.     5,        /*  DrawCount  */
  138.     &BDateBox[0],    /*  vertice coordinates list  */
  139.     NULL        /*  NextBorder  */
  140.     };
  141.  
  142. /*************  StringInfo for BirthDate  *************/
  143. struct StringInfo BDateInfo = {
  144.     datebuffer,    /*  Buffer  */
  145.     NULL,        /*  UndoBuffer  */
  146.     0,        /*  BufferPos  */
  147.     11,        /*  MaxChars  */
  148.     0,        /*  DispPos  */
  149.     NULL,        /*  UndoPos  */
  150.     NULL,        /*  NumChars  */
  151.     NULL,        /*  DispCount  */
  152.     0, 0,        /*  CLeft, CTop  */
  153.     NULL,        /*  LayerPtr  */
  154.     0,        /*  LongInt  */
  155.     NULL        /*  AltKeyMap  */
  156.     };
  157.  
  158. /*************  IntuiText for BirthDate  *************/
  159. struct IntuiText desc_text = {
  160.     1, 0,        /*  FrontPen, BackPen  */
  161.     JAM2,        /*  DrawMode  */
  162.     0, -11,        /*  LeftEdge, TopEdge  */
  163.     &eightyfont,    /*  Font  */
  164.     "Birthdate",    /*  IText  */
  165.     NULL        /*  NextText  */
  166.     };
  167.  
  168. /***************  BirthDate Gadget data  **************/
  169. #define BDATE    1
  170. struct Gadget BirthDate = {
  171.     NULL,        /*  NextGadget  */
  172.     BPOSX, BPOSY,    /*  LeftEdge, TopEdge  */
  173.     88, 8,        /*  Width, Height  */
  174.     GADGHCOMP,    /*  Highlighting  */
  175.     RELVERIFY,    /*  Activation  */
  176.     STRGADGET,    /*  Gadget type  */
  177.     (APTR)&BDateBorder,    /*  Gadget structure  */
  178.     NULL,        /*  SelectRender  */
  179.     &desc_text,    /*  GadgetText  */
  180.     NULL,        /*  MutualExclude  */
  181.     (APTR)&BDateInfo,    /*  SpecialInfo  */
  182.     BDATE,        /*  GadgetID  */
  183.     NULL        /*  UserData  */
  184.     };
  185.  
  186.  
  187. /***************************************************/
  188. /*****************  Arrow Gadgets  *****************/
  189. /***************************************************/
  190.  
  191. /*************  Arrow Gadgets Border  **************/
  192. struct Border BoxBorder = {
  193.     -1, -1,        /*  LeftEdge, TopEdge  */
  194.     3, 0,        /*  FrontPen, BackPen  */
  195.     JAM1,        /*  drawing mode */
  196.     5,        /*  DrawCount  */
  197.     &ArrowBox[0],    /*  vertice coordinates list  */
  198.     NULL        /*  NextBorder  */
  199.     };
  200.  
  201. #define RTARROW    2
  202. struct Gadget RightArrow = {
  203.     &BirthDate,    /*  NextGadget  */
  204.     RPOSX, RPOSY,    /*  LeftEdge, TopEdge  */
  205.     23, 13,        /*  Width, Height  */
  206.     GADGHCOMP,    /*  Highlighting  */
  207.     RELVERIFY,    /*  Activation  */
  208.     BOOLGADGET,    /*  Gadget type  */
  209.     (APTR)&BoxBorder,    /*  Gadget structure  */
  210.     NULL,        /*  SelectRender  */
  211.     NULL,        /*  GadgetText  */
  212.     NULL,        /*  MutualExclude  */
  213.     NULL,        /*  SpecialInfo  */
  214.     RTARROW,    /*  GadgetID  */
  215.     NULL        /*  UserData  */
  216.     };
  217.  
  218. #define LTARROW    3
  219. struct Gadget LeftArrow = {
  220.     &RightArrow,    /*  NextGadget  */
  221.     LPOSX, LPOSY,    /*  LeftEdge, TopEdge  */
  222.     23, 13,        /*  Width, Height  */
  223.     GADGHCOMP,    /*  Highlighting  */
  224.     RELVERIFY,    /*  Activation  */
  225.     BOOLGADGET,    /*  Gadget type  */
  226.     (APTR)&BoxBorder,    /*  Gadget structure  */
  227.     NULL,        /*  SelectRender  */
  228.     NULL,        /*  GadgetText  */
  229.     NULL,        /*  MutualExclude  */
  230.     NULL,        /*  SpecialInfo  */
  231.     LTARROW,    /*  GadgetID  */
  232.     NULL        /*  UserData  */
  233.     };
  234.  
  235.  
  236. /***************************************************/
  237. /****************  Menu Structures  ****************/
  238. /***************************************************/
  239.  
  240. /**************  Intuitext for Menu Item  ************/
  241. struct IntuiText menutext = {
  242.     0, 1,            /*  FrontPen, BackPen  */
  243.     JAM2,            /*  DrawMode  */
  244.     5, 0,            /*  LeftEdge, TopEdge  */
  245.     &eightyfont,        /*  Font  */
  246.     "About",        /*  Text  */
  247.     NULL            /*  NextText  */
  248.     };
  249.  
  250. /**************  MenuItem Structure  *************/
  251. struct MenuItem mymenuitem = {
  252.     NULL,            /*  NextItem  */
  253.     0, 0, 100, 8,        /*  LeftEdge, TopEdge, Width, Height  */
  254.     ITEMTEXT | ITEMENABLED | HIGHCOMP,    /*  Flags  */
  255.     NULL,            /*  MutualExclude  */
  256.     (APTR)&menutext,    /*  ItemFill  */
  257.     NULL,            /*  SelectFill  */
  258.     NULL,            /*  Command  */
  259.     NULL,            /*  SubItem  */
  260.     NULL            /*  NextSelect  */
  261.     };
  262.  
  263. /**************  Menu Structure  ***************/
  264. struct Menu mymenu = {
  265.     NULL,            /*  NextMenu  */
  266.     0, 0, 100, 10,        /*  LeftEdge, TopEdge, Width, Height  */
  267.     MENUENABLED,        /*  Flags  */
  268.     "Project",        /*  MenuName  */
  269.     &mymenuitem
  270.     };
  271.  
  272. /************************************************/
  273. /**************  Window Structure  **************/
  274. /************************************************/
  275.  
  276. struct NewWindow nw = {
  277.     20, 20,            /*  LeftEdge, TopEdge  */
  278.     340, 120,        /*  Width, Height  */
  279.     0, 1,            /*  DetailPen, BlockPen  */
  280.     CLOSEWINDOW | GADGETUP | NEWSIZE |
  281.         SIZEVERIFY | MENUPICK,        /*  IDCMP Flags  */
  282.  
  283.     WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWSIZING |
  284.         WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH,    /*  WindowFlags  */
  285.  
  286.     &LeftArrow,        /*  FirstGadget  */
  287.     NULL,            /*  CheckMark  */
  288.     "Biorhythm Calculator v1.1",    /*  Title  */
  289.     NULL, NULL,        /*  Screen, BitMap  */
  290.     340, 130,        /*  MinWidth, MinHeight  */
  291.     640, 440,        /*  MaxWidth, MaxHeight  */
  292.     WBENCHSCREEN        /*  Type  */
  293.     };
  294.  
  295.  
  296. /*****  IMPORTANT!  *****
  297.  
  298.     We use _main() here because when you compile with Lattice and main(),
  299.     a console window will be automatically opened when the program is
  300.     run from Workbench.  Using _main() prevents this, and also saves LOTS
  301.     of object code.  NOTE:  I gleaned this technique from the version of
  302.     gfxmem on FISH disk 14.  I do not know the possible side effects of
  303.     using _main(), and am not real clear on why it works in the first
  304.     place, so use it with CAUTION.
  305. */
  306.  
  307. _main()
  308. {
  309.     ULONG class;        /*  IDCMP message class  */
  310.     USHORT code;        /*  IDCMP message code   */
  311.     int i;
  312.  
  313.     /**********  Open the Libraries needed  **********/
  314.  
  315.     if(!OpenMathLibs()) exit(FALSE);    /*  open Motorola FFP libs.  */
  316.                 /*  NOTE:  OpenMathLibs() is in  ffp.h  */
  317.  
  318.     if ((IntuitionBase = (struct IntuitionBase *)
  319.         OpenLibrary("intuition.library", INTUITION_REV)) == NULL)
  320.         {
  321.         CloseMathLibs();
  322.         exit(FALSE);
  323.         }
  324.  
  325.     if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0))
  326.         == NULL)  
  327.         {
  328.         CloseMathLibs();
  329.         CloseLibrary (IntuitionBase);
  330.         exit(FALSE);
  331.         }
  332.  
  333.     /**********  Open the Window  **********/
  334.      
  335.     if ( (MyWindow = OpenWindow(&nw) ) == NULL)
  336.         {
  337.         CloseMathLibs();
  338.         CloseLibrary(IntuitionBase);
  339.         CloseLibrary(GfxBase);
  340.         exit(FALSE);
  341.         }
  342.  
  343.     rp = MyWindow->RPort;            /*  RastPort pointer  */
  344.  
  345.     if (font = OpenFont(&eightyfont))    /*  Set font to 80-columns  */
  346.         {
  347.         SetFont(rp, font);
  348.         CloseFont(font);
  349.         }
  350.     
  351.     SetMenuStrip(MyWindow, &mymenu);    /*  Activate pull-down menu  */
  352.  
  353.     /*****  set up About requester text  *****/
  354.  
  355.     for (i = 0; i <= REQLINES - 1; i++)
  356.         {
  357.         aboutarray[i] = texttemplate;
  358.         aboutarray[i].IText = aboutdata[i];
  359.         aboutarray[i].TopEdge = 6 + i * 9;
  360.         aboutarray[i].LeftEdge = REQWIDTH / 2 - 11 -
  361.                     IntuiTextLength(&aboutarray[i]) / 2;
  362.         }
  363.  
  364.     for (i = 0; i <= REQLINES - 2; i++)
  365.         aboutarray[i].NextText = &aboutarray[i + 1];
  366.  
  367.  
  368.     /*****  IEEE to FFP conversions  *****/
  369.     pmult = makeFFP(PMULT);
  370.     emult = makeFFP(EMULT);
  371.     imult = makeFFP(IMULT);
  372.  
  373.     drawtriangles();            /*  Draw filled triangles  */
  374.     displegend();                /*  Display graph identifiers */
  375.  
  376.     Get_Date(&sysdate);            /*  get system date  */
  377.     sysdate.days = 1;            /*  set to 1st day of year  */
  378.     birthdate = sysdate;            /*  set birthdate to sysdate  */
  379.     newmonth();                /*  display graph  */
  380.  
  381. /*
  382.  **************************  Main Program Loop  ***************************
  383. */
  384. do
  385.     {
  386.     Wait( 1L << MyWindow->UserPort->mp_SigBit);   /*  Wait for an event  */
  387.  
  388.     while ( IMsg = GetMsg(MyWindow->UserPort) )
  389.         {
  390.  
  391.         class = IMsg->Class;
  392.         code  = IMsg->Code;
  393.  
  394.         switch (class)    {
  395.  
  396.         case GADGETUP : dogadgets( (struct Gadget *)IMsg->IAddress );
  397.                 break;
  398.  
  399.         case NEWSIZE  : drawgraph();
  400.                 break;
  401.  
  402.         case MENUPICK : if (MENUNUM(code) != MENUNULL)
  403.                     domenu(MENUNUM(code),ITEMNUM(code));
  404.                 break;
  405.  
  406.             }
  407.  
  408.         ReplyMsg(IMsg);        /*  tell IDCMP you got it  */
  409.         }
  410.     }
  411. while (class != CLOSEWINDOW);        /*  do until user closes window  */
  412.  
  413.  
  414. /*
  415.                 F I N I S H   U P
  416.  
  417.  
  418.       ******  Free allocated memory, close open Libraries, and quit  ******
  419. */
  420.  
  421.     FreeRemember (&RememberKey, TRUE);    /*  free all allocated memory */
  422.  
  423.     FreeRaster(MyPlane,AREAX,AREAY);    /*  free allocated rasters  */
  424.     CloseWindow(MyWindow);            /*  close window  */
  425.     CloseLibrary(IntuitionBase);
  426.     CloseLibrary(GfxBase);
  427.     CloseMathLibs();            /*  close FFP Libraries  */
  428. }
  429.  
  430.  
  431. void drawtriangles()        /***  Draw interior of Arrow gadgets  ***/
  432. {
  433.     UBYTE *InitAreaPtr, *AllocRemember();
  434.     struct AreaInfo MyAreaInfo;
  435.  
  436.     RememberKey = NULL;
  437.     InitAreaPtr = AllocRemember(&RememberKey, MAXPOINTS * 5, MEMF_CHIP);
  438.         /*  allocate enough memory for figures with MAXPOINTS pts.   */
  439.  
  440.     InitArea(&MyAreaInfo, InitAreaPtr, MAXPOINTS);    /* create work area  */
  441.     rp->AreaInfo = &MyAreaInfo;
  442.  
  443.     MyPlane = (PLANEPTR) AllocRaster(AREAX,AREAY);
  444.                     /* reserve memory for drawing*/
  445.     if (MyPlane == 0L) exit(FALSE);  /*  not able to allocate memory  */
  446.     rp->TmpRas = (struct TmpRas *) InitTmpRas(&MyTmpRas,
  447.                         MyPlane, RASSIZE(AREAX,AREAY) );
  448.  
  449.  
  450.     /*******  Going to draw 2 filled triangles  *******/
  451.  
  452.     SetAPen(rp, 2);        /*  going to use color #2  */
  453.     SetBPen(rp, 0);        /*  use color #0 for bkgnd  */
  454.     SetOPen(rp, 1);        /*  outline around triangles  */
  455.     SetDrMd(rp, JAM1);    /*  Draw Mode  */
  456.  
  457.     AreaMove (rp, LPOSX+Arrow1[0],LPOSY+Arrow1[1]);        /* 1st vert. */
  458.     AreaDraw (rp, LPOSX+Arrow1[2],LPOSY+Arrow1[3]);        /* 2nd vert. */
  459.     AreaDraw (rp, LPOSX+Arrow1[4],LPOSY+Arrow1[5]);        /* 3rd vert. */
  460.     AreaEnd (rp);    /*  finish and fill left triangle  */
  461.  
  462.     AreaMove (rp, RPOSX+Arrow2[0],RPOSY+Arrow2[1]);        /* 1st vert. */
  463.     AreaDraw (rp, RPOSX+Arrow2[2],RPOSY+Arrow2[3]);        /* 2nd vert. */
  464.     AreaDraw (rp, RPOSX+Arrow2[4],RPOSY+Arrow2[5]);        /* 3rd vert. */
  465.     AreaEnd (rp);    /*  finish and fill right triangle  */
  466. }
  467.  
  468.  
  469. void displegend()    /********  Display key to graph  *********/
  470. {
  471.     SetDrMd(rp, JAM1);        /*  Drawing mode  */
  472.     SetAPen(rp, BKGD);        /*  Background color of graph  */
  473.     SetOPen(rp, 3);            /*  Outline for box  */
  474.     RectFill(rp, 17, LEGY-8, 291, LEGY+3);
  475.  
  476.     SetAPen(rp, PHYSPEN);        /*  Color of Physical graph  */
  477.     Move(rp, 20, LEGY);        /*  Move into position  */
  478.     Text(rp, "Physical", 8);
  479.  
  480.     SetAPen(rp, EMOTPEN);        /*  Color of Emotional graph  */
  481.     Move(rp, 105, LEGY);
  482.     Text(rp, "Emotional", 9);
  483.  
  484.     SetAPen(rp, INTEPEN);        /*  Color of Intellectual graph  */
  485.     Move(rp, 194, LEGY);
  486.     Text(rp, "Intellectual", 12);
  487. }
  488.  
  489.  
  490. void drawgraph()    /********  Draw graph  *******/
  491. {
  492.     int ymax, y, ysize;
  493.     int xmax, x, xsize;
  494.     int rem, count, length, junk;
  495.     char string[6];
  496.     FFP daywidth, halfysize;
  497.     FFP fy, inc, factor;
  498.  
  499.     xmax = MyWindow->Width - MyWindow->BorderRight - 8;
  500.     ymax = MyWindow->Height - 21;        /*  need space at bottom  */
  501.     ysize = ymax - GRAPHY;            /*  for dates          */
  502.  
  503.     SetAPen(rp, 0);            /*  drawing color, 0 is background  */
  504.     BNDRYOFF(rp);            /*  no boundary on this rectangle  */
  505.     SetDrMd(rp, JAM1);        /*  drawing mode, just JAM it in  */
  506.     RectFill (rp, 2, GRAPHY,
  507.         MyWindow->Width - MyWindow->BorderRight, MyWindow->Height - 2);
  508.         /**  clear graph area  **/
  509.  
  510.     SetAPen(rp, 1);            /*  pen color  */
  511.     SetOPen(rp, 2);            /*  outline pen  */
  512.     SetDrMd(rp, JAM1);        /*  drawing mode  */
  513.     RectFill (rp, GRAPHX, GRAPHY, xmax, ymax);    /*  Draw box  */
  514.  
  515.     SetDrPt(rp, 0xf8f8);        /*  line-drawing pattern  */
  516.     SetAPen(rp, 3);            /*  line color  */
  517.     SetBPen(rp, 1);            /*  background color  */
  518.     y = GRAPHY + (ysize / 2);    /*  Y position of dotted line  */
  519.     Move(rp, GRAPHX + 1, y);
  520.     Draw(rp, xmax - 1, y);        /*  draw dotted line  */
  521.  
  522.     SetAPen(rp, 3);
  523.     Move(rp, 11, GRAPHY + 7);
  524.     Text(rp, "Hi", 2);
  525.     Move(rp, 19, y + 3);
  526.     Text(rp, "0", 1);
  527.     Move(rp, 3, ymax - 1);
  528.     Text(rp, "Low", 3);
  529.  
  530.     xsize = xmax - 1 - GRAPHX;    /*  usable X area  */
  531.     daywidth = SPDiv(numdays, SPFlt(xsize));
  532.  
  533.     /*****  Display line & date every 5th day  *****/
  534.     /***  NOTE:  lines are at midnight (12:00am)  ***/
  535.     SetDrPt(rp, 0x8888);        /*  sparse dotted line  */
  536.     SetDrMd(rp, JAM1);        /*  drawing mode  */
  537.     for (count = 5; count <= SPFix(numdays); count += 5)
  538.         {
  539.         SetAPen(rp, 0);            /*  line color  */
  540.         x = GRAPHX + SPFix(SPMul(SPFlt(count-1),daywidth));
  541.         Move(rp, x, GRAPHY + 1);
  542.         Draw(rp, x, ymax - 1);
  543.         SetAPen(rp, 1);            /*  text color  */
  544.         length = stci_d(string, count, &junk);
  545.         Move(rp, x - 8 * (length - 1), ymax + 9);  /* text placement */
  546.         Text(rp, string, length);
  547.         }
  548.  
  549.     y = MyWindow->Height - 4;        /*  position for month name  */
  550.     SetAPen(rp, 2);
  551.     SetBPen(rp, 1);
  552.     SetDrMd(rp, JAM2);
  553.     Move(rp, GRAPHX, y);
  554.     count = strlen(monthname[month-1]);
  555.     Text(rp, monthname[month-1], count);    /*  display month name  */
  556.     Text(rp, " ", 1);
  557.     length = stci_d(string, (long) sysdate.year, &junk);
  558.     Text(rp, string, length);        /*  display year  */
  559.  
  560.     SetDrPt(rp, 0xffff);        /*  reset drawing pattern  */
  561.  
  562.     halfysize = SPFlt(ysize / 2 - 1);
  563.  
  564.     SetDrMd(rp, JAM1);        /*  drawing mode  */
  565.  
  566.     inc = SPDiv(daywidth, SPFlt(1));
  567.  
  568.     /***************  Draw Physical cycle  ***************/
  569.     SetAPen(rp, PHYSPEN);
  570.     rem = dayspan % PHYSICAL;
  571.     factor = SPAdd(SPFlt(rem),inc);
  572.  
  573.     for ( x = 1; x <= xsize; x++ )
  574.         {
  575.         fy = SPMul(halfysize, SPNeg(SPSin(SPDiv(pmult,factor))));
  576.         WritePixel(rp, GRAPHX +x, GRAPHY +2+SPFix(SPAdd(fy,halfysize)));
  577.         factor = SPAdd(factor, inc);
  578.         }
  579.  
  580.     /***************  Draw Emotional cycle  ***************/
  581.     SetAPen(rp, EMOTPEN);
  582.     rem = dayspan % EMOTIONAL;
  583.     factor = SPAdd(SPFlt(rem),inc);
  584.  
  585.     for ( x = 1; x <= xsize; x++ )
  586.         {
  587.         fy = SPMul(halfysize, SPNeg(SPSin(SPDiv(emult,factor))));
  588.         WritePixel(rp, GRAPHX +x, GRAPHY +2+SPFix(SPAdd(fy,halfysize)));
  589.         factor = SPAdd(factor, inc);
  590.         }
  591.  
  592.     /***************  Draw Intellectual cycle  ***************/
  593.     SetAPen(rp, INTEPEN);
  594.     rem = dayspan % INTELLECTUAL;
  595.     factor = SPAdd(SPFlt(rem),inc);
  596.  
  597.     for ( x = 1; x <= xsize; x++ )
  598.         {
  599.         fy = SPMul(halfysize, SPNeg(SPSin(SPDiv(imult,factor))));
  600.         WritePixel(rp, GRAPHX +x, GRAPHY +2+SPFix(SPAdd(fy,halfysize)));
  601.         factor = SPAdd(factor, inc);
  602.         }
  603. }
  604.  
  605.  
  606. void dogadgets(gad)    /********  gadget handling   *******/
  607. struct Gadget *gad;
  608. {
  609.     switch (gad->GadgetID)    {
  610.  
  611.     case LTARROW  : sysdate.days -= 1;
  612.             if (sysdate.days < 1)
  613.                 {
  614.                 sysdate.year -= 1;
  615.                 if (sysdate.year % 4)
  616.                     sysdate.days += 365;
  617.                 else
  618.                     sysdate.days += 366;
  619.                 }
  620.             newmonth();        /*  calc. day & draw graph  */
  621.             break;
  622.  
  623.     case RTARROW  : sysdate.days += SPFix(numdays);
  624.             if (sysdate.days > 365 && sysdate.year % 4)
  625.                 {
  626.                 sysdate.year += 1;
  627.                 sysdate.days -= 365;
  628.                 }
  629.             else
  630.             if ( (sysdate.year % 4 == 0) && sysdate.days > 366)
  631.                 {
  632.                 sysdate.year += 1;
  633.                 sysdate.days -= 366;
  634.                 }
  635.             newmonth();
  636.             break;
  637.  
  638.     case BDATE    : Get_Date(&sysdate);        /*  get system date  */
  639.             GregtoJul(&birthdate, datebuffer);
  640.             if ( birthdate.year == 0 )    /*  invalid date  */
  641.                 {
  642.                 sysdate.days = 1;
  643.                 birthdate = sysdate;
  644.                 }
  645.             newmonth();
  646.             break;
  647.     }
  648. }
  649.  
  650.  
  651. void newmonth()
  652. {
  653.     int daycount, curday;
  654.  
  655.     curday = Datestat(&sysdate, &daycount,&month);
  656.     numdays = SPFlt(daycount);            /*  no. of days in month  */
  657.     sysdate.days = sysdate.days - curday + 1;
  658.     dayspan = Date_Span(&birthdate, &sysdate);
  659.     drawgraph();
  660.  
  661.     /***  NOTE:  sysdate no longer contains the  ***
  662.      ***  current date, but rather the date of   ***
  663.      ***  the 1st day of the month.              **/
  664. }
  665.  
  666.  
  667. /*
  668.     NOTE:  This is a very simplistic way of handling menu events.  In all
  669.     probability you would not want to handle large menus this way.  With
  670.     only one menu option, I did not think it practical to write a formal
  671.     procedure to handle it.
  672. */
  673.  
  674. void domenu(menu, item)
  675. USHORT menu, item;
  676. {
  677.     switch (menu)  {
  678.  
  679.     case 0 :    switch (item)  {
  680.  
  681.             case 0 : AutoRequest(MyWindow, aboutarray, NULL,
  682.                     &OkText, NULL,NULL,REQWIDTH, REQHEIGHT);
  683.             }
  684.             break;
  685.     }
  686. }
  687.